3分で作る、S3イベントで実行するLambda
前回の S3イベントバージョンです。Chaliceを使ってS3の各種イベントをトリガーにLambdaを起動してみたいと思います。
環境
- macOS Catalina 10.15.4
- Python 3.7.7
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.4 BuildVersion: 19E287 $ python3 -VV Python 3.7.7 (default, Mar 10 2020, 15:43:33) [Clang 11.0.0 (clang-1100.0.33.17)]
やってみる
仮想環境の作成
今回は Python で標準機能の venv
を利用します。
$ mkdir chalice-example && cd chalice-example $ python3 -m venv venv
仮想環境の有効化
$ source ./venv/bin/activate (venv) $
Chaliceのインストール
(venv) $ pip install chalice
パッケージのインストール
画像処理に使用するパッケージをインストールします。
(venv) $ pip install boto3 Pillow
プロジェクトの作成
new-project
コマンドを利用してプロジェクトの雛形を作成します。s3-event-lambda フォルダが作成され、各種ファイルが作成されています。
(venv) $ chalice new-project s3-event-lambda
コーディング
app.py
の内容を下記のようにします。処理内容は指定したバケットにオブジェクトが作成された時に、キーが prefix
、suffix
に合致するものを通知対象としています。画像のリサイズを行い、別のバケットにアップロードしています。
import logging import uuid import boto3 from PIL import Image from chalice import Chalice from chalice.app import S3Event app = Chalice(app_name='s3-event-lambda') app.log.setLevel(logging.INFO) s3 = boto3.client('s3') def resize_image(image_path, resized_path): with Image.open(image_path) as image: image.thumbnail(tuple(x / 2 for x in image.size)) image.save(resized_path) @app.on_s3_event(bucket='chalice-s3-event-demo', # 必須: 対象バケット名 events=['s3:ObjectCreated:*'], # オプション: 対象イベント (省略時は s3:ObjectCreated:*) prefix='images/', # オプション: 対象プレフィックス suffix='jpg', # オプション: 対象サフィックス name='resize-image') # オプション: Lambda名 (省略時は関数名を使用) def lambda_handler(event: S3Event): bucket = event.bucket key = event.key tmp_key = key.replace('/', '') image_path = '/tmp/{}{}'.format(uuid.uuid4(), tmp_key) resized_path = '/tmp/resized-{}'.format(tmp_key) s3.download_file(bucket, key, image_path) resize_image(image_path, resized_path) s3.upload_file(resized_path, '{}-resized'.format(bucket), key) app.log.info("resized image: %s", event.key)
必要なライブラリの設定
実行に必要なライブラリを requirements.txt
に記載します。これによりデプロイ時に一緒にアップロードされます。
(venv) $ pip freeze | grep boto3 >> requirements.txt (venv) $ pip freeze | grep Pillow >> requirements.txt (venv) $ cat requirements.txt boto3~=1.12.42 Pillow~=7.1.1
S3バケットの作成
画像をアップロードするバケットと、リサイズした画像をアップロードするバケットを作成します。バケット名はユニークである必要があるので、ソースコードとあわせて適宜変更してください。
$ aws s3 mb s3://chalice-s3-event-demo make_bucket: chalice-s3-event-demo $ aws s3 mb s3://chalice-s3-event-demo-resized make_bucket: chalice-s3-event-demo-resized
デプロイ
(venv) $ chalice deploy --stage dev Creating deployment package. Creating IAM role: s3-event-lambda-dev Creating lambda function: s3-event-lambda-dev-resize-image Configuring S3 events in bucket chalice-s3-event-demo to function s3-event-lambda-dev-resize-image Resources deployed: - Lambda ARN: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:s3-event-lambda-dev-resize-image
作成されたものを確認
Lambda
IAMロール
ポリシーにS3の権限が自動で付与されています。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:GetObject", "s3:PutObject" ], "Resource": [ "*" ], "Sid": "49a732cbfcc7454f8c3fc9ced179612d" }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" } ] }
S3バケットのイベント設定
オブジェクトの作成イベントでLambdaが呼び出される設定になっています。
動作確認
S3にトリガー条件に適合する画像をアップロードして見ます。
リサイズ用のバケットを確認します。Lambdaによってリサイズ処理されていることが分かります。
ログを確認します。
後片付け
次のコマンドで作成したリソースが削除できます。ロググループは削除されないので手動で消す必要があります。
(venv) $ chalice delete --stage dev
指定できるイベント
下記が指定できるイベント一覧です。複数組み合わせて指定することができます。詳細はAWSドキュメントをご参照ください。
Amazon S3 イベント通知の設定 - Amazon Simple Storage Service
- s3:ObjectCreated:*
- s3:ObjectCreated:Put
- s3:ObjectCreated:Post
- s3:ObjectCreated:Copy
- s3:ObjectCreated:CompleteMultipartUpload
- s3:ObjectRemoved:*
- s3:ObjectRemoved:Delete
- s3:ObjectRemoved:DeleteMarkerCreated
- s3:ObjectRestore:Post
- s3:ObjectRestore:Completed
- s3:ReducedRedundancyLostObject
- s3:Replication:OperationFailedReplication
- s3:Replication:OperationMissedThreshold
- s3:Replication:OperationReplicatedAfterThreshold
- s3:Replication:OperationNotTracked
さいごに
スケジュール実行と同様に非常に簡単にS3イベントと連携できるLambdaが作成できました。